iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 21
3
Day 21

這邊刪一下、那邊加一下,阿不,從後面改起!主管,可不可以不要這樣玩來玩去嗎?

splice 中文為拼接。可以藉由刪除原來有的元素並/或加入新元素來改變一個陣列的內容。

但其實splice()不只會拼接,還可以指定在哪個點刪除與增加元素,且一次還可以增加多個。剛開始使用splice()常記不起來三個參數的含義,我們可以用這個比喻來增加記憶:

想像主管請我們做一個產品介紹的投影片,花了一整天終於把投影片做好 這樣算慢嗎?,拿去給主管看時,主管看了看說,啊這樣不行啦,你都沒放產品的側面和背面介紹,你從第三頁(start)那裡開始,把都是文字的那頁(deleteCount)使用說明拿掉,再把我說的側面和背面介紹兩頁(item1, item2)放進去,這樣就會更完美了。。

我們也發現,splice()比起上一篇介紹,可淺拷貝的 slice()似乎更有彈性。

https://ithelp.ithome.com.tw/upload/images/20191006/20104175tzA52W0iCV.png
Array.prototype.splice() - JavaScript | MDN

原型: Array.prototype.splice()
功能: 可以藉由刪除既有元素並/或加入新元素來改變一個陣列的內容。
改變: 會改變原陣列。
語法: var arrDeletedItems = array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
回傳值: 一個包含被刪除的元素陣列。如果只有一個元素被刪除,依舊是回傳包含一個元素的陣列。 倘若沒有元素被刪除,則會回傳空陣列。
參數: start[, deleteCount[, item1[, item2[, ...]]]], start是必須的。

因為splice()的參數有點小複雜,所以我們特別來看一下。直接語意說明:arr1.splice(要插入或刪除的索引位置, 要刪除的元素數量, 要插入的元素內容)。我們先預設這些參數的代稱:splice(start, deleteCount, item )這樣範例會比較清楚。只是要記住,splice()本身所回傳回來的,會是我們刪除掉的元素陣列,而不是使用splice()之後原陣列的結果,如果希望得到原陣列的結果,需要指派另一個變數去接。

下面的範例我們會從索引值 1 的地方刪除 2 個元素,並將"hi"這個字串放進去。

const colors1 = ["red", "yellow", "blue", "gray", "purple"]
const colors2 = colors1.splice(1, 2, "hi")

colors1; // ["red", "hi", "gray", "purple"]
colors2; // ["yellow", "blue"]

刪了幾個,就回傳幾個刪掉的元素陣列回來

在使用splice()的時候,如果只給start,而省略deleteCount,或是start的值,大於原陣列長度減掉start(也就是deleteCount大於start算起的剩餘元素數量),那麼splice()就會把所有從start開始到陣列到最後一個元素都刪除。

const colors1 = ["red", "yellow", "blue", "gray", "purple"]
const colors2 = colors1.splice(1); // 從索引值 1 的點開始刪除到全部
colors1; //["red"]
colors2; //["yellow", "blue", "gray", "purple"] // 把刪除的元素通通傳回來

如果是colors1.splice(0);,那麼我們會得到一個空陣列[],也就是說全部的元素都刪除掉。

只是想插隊一下的 deleteCount = 0

我們可以利用splice()單純做到在一個陣列裡插入元素,方法很簡單,只要把deleteCount設為零就可以了。我們甚至可以一次插入多個元素。當然,回傳的結果會是[ ]空陣列,因為我們什麼都沒刪,如果deleteCount是負數,也會得到和 0 一樣的結果。反之colors1卻獲得了增加一個數字42的陣列。

const colors1 = ["red", "yellow", "blue", "gray", "purple"]
const colors2 = colors1.splice(1, 0, 42)
colors1; // ["red", 42, "yellow", "blue", "gray", "purple"]
colors2;  // []

索引值也可以從後頭開始算

splice()start接受負數,當我們使用負數的索引值,也表示我們要從陣列的尾端數回來。但是請小心,雖然是 -1 但並不是從尾端直接增加元素,而是從尾端倒數第一個的那個點新增元素,所以,原本最後一個元素會被往後擠。

const colors1 = ["red", "yellow", "blue", "gray", "purple"]
const colors2 = colors1.splice(-1, 0, 42)

colors1; // ["red", "yellow", "blue", "gray", 42, "purple"]
colors2; // []

常常被拿來和 slice 比較

常常會看到splice()slice()比較的文章,但是倒底兩個方法還是有很大的不同的。
slice()不會改變原陣列;splice()會。
slice()回傳指定切下來的陣列;splice()會回傳被刪除的陣列。
如果想快速獲得一個淺拷貝的陣列,的確slice()顯得簡潔,但其實splice()也不差,還可以用另ㄧ變數指定的方式,輕易獲得新增或刪除的陣列,用哪個比較方便,就真的要看使用情境了。

希望今天的小菜大家都還喜歡,其實還有許多不同的用法,礙於篇幅與時間無法一一介紹,希望鐵人賽之後,可以有時間把這些介紹做得更詳細些啊。

如有需要改進的地方,拜託懇求請告知,我會盡量快速度修改,感謝您~


上一篇
輕鬆淺拷貝的陣列 Array 方法 slice()
下一篇
JS 將陣列 Array 重新排列的 sort()
系列文
JavaScript之一定要了解的 Array 與方法34
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
WILL.I.AM
iT邦新手 3 級 ‧ 2022-01-25 12:29:50

錯別字: splice()的start接受複數 => 負數

tsuifei iT邦新手 4 級 ‧ 2022-02-26 15:37:26 檢舉

非常感謝~已更正。

我要留言

立即登入留言